import { deepClone } from '@/util'
import db from "@/util/localstorage";
import Layout from '@/layout'
import EmptyLayout from '@/layout/empty'

function hasPermission(permissions, route) {
    let isAuth = false;
    if (route.meta && route.meta.auth) {
        isAuth = permissions.some(auth => {
            if (typeof route.meta.auth == 'string') {
                return route.meta.auth === auth
            } else {
                return route.meta.auth.some(routeAuth => {
                    return routeAuth === auth
                })
            }
        })
    } else {
        isAuth = true
    }
    return isAuth
}

function filterAsyncRoutes(routes) {
    const res = [];
    routes.forEach(route => {
        const tmp = { ...route };
        // if (hasPermission(permissions, tmp)) {
            const component = tmp.component;
            if (component) {
                if (tmp.component === 'Layout') {
                    tmp.component = Layout
                }else if (tmp.component === 'EmptyLayout') {
                    tmp.component = EmptyLayout
                } else if (typeof component === 'string') {
                    tmp.component = view(component)
                }
                if (tmp.children) {
                    tmp.children = filterAsyncRoutes(tmp.children);
                    tmp.children.length && res.push(tmp)
                }else {
                    res.push(tmp)
                }
            }else {
                if (tmp.children) {
                    tmp.children = filterAsyncRoutes(tmp.children);
                    tmp.children.length && res.push(tmp)
                } else {
                    res.push(tmp)
                }
            }
        // }
    });
    return res
}

function view(path) {
    return function (resolve) {
        require([`@/views/${path}.vue`], resolve)
    }
}

// 将多层嵌套路由处理成平级
function flatAsyncRoutes(routes, breadcrumb, baseUrl = '') {
    let res = [];
    routes.forEach(route => {
        const tmp = { ...route };
        if (tmp.children) {
            let childrenBaseUrl = '';
            if (baseUrl === '') {
                childrenBaseUrl = tmp.path
            } else if (tmp.path !== '') {
                childrenBaseUrl = `${baseUrl}/${tmp.path}`
            }
            let childrenBreadcrumb = deepClone(breadcrumb);
            if (route.meta.breadcrumb !== false) {
                childrenBreadcrumb.push({
                    path: childrenBaseUrl,
                    title: route.meta.title
                })
            }
            let tmpRoute = deepClone(route);
            tmpRoute.path = childrenBaseUrl;
            tmpRoute.meta.breadcrumbNeste = childrenBreadcrumb;
            delete tmpRoute.children;
            res.push(tmpRoute);
            let childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb, childrenBaseUrl);
            childrenRoutes.map(item => {
                // 如果 path 一样则覆盖，因为子路由的 path 可能设置为空，导致和父路由一样，直接注册会提示路由重复
                if (res.some(v => v.path === item.path)) {
                    res.forEach((v, i) => {
                        if (v.path === item.path) {
                            res[i] = item
                        }
                    })
                } else {
                    res.push(item)
                }
            })
        } else {
            if (baseUrl !== '') {
                if (tmp.path !== '') {
                    tmp.path = `${baseUrl}/${tmp.path}`
                } else {
                    tmp.path = baseUrl
                }
            }
            // 处理面包屑导航
            let tmpBreadcrumb = deepClone(breadcrumb);
            if (tmp.meta.breadcrumb !== false) {
                tmpBreadcrumb.push({
                    path: tmp.path,
                    title: tmp.meta.title
                })
            }
            tmp.meta.breadcrumbNeste = tmpBreadcrumb;
            res.push(tmp)
        }
    });
    return res
}

const state = {
    isGenerate: false,
    routes: [],
    headerActived: 0
};

const getters = {
    sidebarRoutes: state => {
        return state.routes[state.headerActived].children
    }
};

const actions = {
    // 根据权限动态生成路由
    generateRoutes({rootState, dispatch, commit}, data) {
        // eslint-disable-next-line no-async-promise-executor
        return new Promise(async resolve => {
            let accessedRoutes;
            // 判断权限功能是否开启
            // const permissions = await dispatch('user/getPermissions', null, { root: true })
            // const permissions = db.get('PERMISSIONS');
            //加载路由
            accessedRoutes = filterAsyncRoutes(data.asyncRoutes);
            commit('setRoutes', accessedRoutes);
            commit('setHeaderActived', data.currentPath);
            let routes = [];
            accessedRoutes.map(item => {
                routes.push(...item.children)
            });
            // console.log(rootState.settings.enableFlatRoutes);
            if (rootState.settings.enableFlatRoutes) {
                routes.map(item => {
                    if (item.children) {
                        item.children = flatAsyncRoutes(item.children, [{
                            path: item.path,
                            title: item.meta.title
                        }])
                    }
                })
            }
            resolve(routes)
        })
    }
};

const mutations = {
    invalidRoutes(state) {
        state.isGenerate = false;
        state.headerActived = 0
    },
    setRoutes(state, routes) {
        state.isGenerate = true;
        let newRoutes = deepClone(routes);
        state.routes = newRoutes.filter(item => {
            return item.children.length !== 0
        })
    },
    // 根据路由判断属于哪个头部导航
    setHeaderActived(state, path) {
        state.routes.map((item, index) => {
            if (
                item.children.some(r => {
                    return path.indexOf(r.path + '/') === 0 || path === r.path
                })
            ) {
                state.headerActived = index
            }
        })
    },
    // 切换头部导航
    switchHeaderActived(state, index) {
        state.headerActived = index
    }
};

export default {
    namespaced: true,
    state,
    actions,
    getters,
    mutations
}
